'''
Created on 6-Jul-09

@author: jm
'''

from django.utils import simplejson as json
from google.appengine.ext.webapp import RequestHandler

from model.Session import *
from model.Revision import Revision 

import logging
from server.Utils import *

POST_PATH="__post__" # path to identify a post treatment
HOME_PAGE="/admin"
DEFAUT_LANGUAGE="en"
MES={}
MES["elapsed"]="elapsed"


def checkSession(sid):
    ''' check session and create message '''
    errorMessage=""
    session,code=SessionManagement.checkSession(sid)
    if session:
        logging.debug("CHECK OLD SESSION="+sid+"->"+str(session.ID))
    else:
        logging.debug("CHECK OLD SESSION="+sid+"->  Expired or Timeout or Error")
        session=None
    if code == SessionCode.SESSION_SEQUENCE: errorMessage="Session Error"
    elif code == SessionCode.SESSION_MAXLIFE: errorMessage="Session Life Eime reached"
    elif code == SessionCode.SESSION_TIMEOUT: errorMessage="Session Timeout"
    elif code == SessionCode.SESSION_ERROR: errorMessage="Session Error"
    elif code == SessionCode.SESSION_NOT_FOUND: errorMessage="Session Not Found"
    elif code == SessionCode.SESSION_DOUBLE_CLICK: errorMessage="Double Click Detected"
    elif code == SessionCode.SESSION_RELOAD: errorMessage="Reload (refresh) Detected"
    if errorMessage != "": logging.info((session and "session="+session.nextID+" " or "")+errorMessage)
    return (session,code,errorMessage)


class SessionHandler(RequestHandler):
    """     Base class of all our normal request handlers which makes sure we keep a session
            The session timeout is high
    """

#  HOME_URL = "/"
#  BASE_URL = "/"

    def headers(self,l=None):
        self.response.headers['Content-Type'] = 'text/plain'
        if l: self.response.headers['Content-Length'] = l
        self.response.headers['Expires'] = -1
        self.response.headers['Cache-Control'] = 'no-cache'
        self.response.headers['Pragma'] = 'no-cache'
  
    def abort(self,s,http=HTTP_UNAUTHORIZED):
        logging.error("Internal error: "+str(s))
        self.error(http)
        self.response.out.write("ERROR: "+str(s)+". Please try again.")
        #exit()

    def getResponse(self):
        """ 
        Handler for get or post 
        """
    
        self.language=DEFAUT_LANGUAGE
        self.errorMessage = ""
        self.errorCode = SessionCode.SESSION_OK
    
        self.path_list = self.request.path.strip('/').split('/')
    
        if not hasattr(self,"outputPhase"):
            self.abort("No Output Phase")
            return 
        if self.sid=='':
            self.newSession=True
            self.session=SessionManagement.startSession()
            self.sid=self.session.nextID
            logging.info("==== NEW SESSION="+str(self.session.ID))
            if hasattr(self,"generationPhase"): self.generationPhase()
            return self.outputPhase() # or redirect
        else:
            self.newSession=False
            self.session,self.errorCode,self.errorMessage=checkSession(self.sid)
            if self.errorCode == SessionCode.SESSION_RELOAD:
                # if self.sid == self.session.displayedID:
                logging.info("Session reload: ID=%s, seq=%d, disp=%s, next=%s, request=%s",self.session.ID,self.session.sequence,self.session.displayedID,self.session.nextID,self.sid)
                self.sid=self.session.nextID
                return self.outputPhase()
            elif self.errorCode == SessionCode.SESSION_DOUBLE_CLICK:
                logging.info("Session double click: ID=%s, seq=%d, disp=%s, next=%s, request=%s",self.session.ID,self.session.sequence,self.session.displayedID,self.session.nextID,self.sid)
                self.sid=self.session.nextID
                return self.outputPhase()
            elif self.errorCode == SessionCode.SESSION_OK:
                logging.info("Session OK: ID=%s, seq=%d, disp=%s, next=%s, request=%s",self.session.ID,self.session.sequence,self.session.displayedID,self.session.nextID,self.sid)
                self.sid=self.session.nextID
                logging.debug(self.path_list[-1] +"-"+ POST_PATH +"-"+ self.POST_PHASE)
                if self.path_list[-1] == POST_PATH:
                    if hasattr(self,self.POST_PHASE): 
                        return getattr(self,self.POST_PHASE)()
                #if self.sid == self.session.nextID:
                if hasattr(self,"generationPhase"): self.generationPhase()
                return self.outputPhase() # or redirect
            else:
                logging.info("Incorrect Session : ID=%s, seq=%d, disp=%s, next=%s, request=%s",
                             self.session.ID,self.session.sequence,self.session.displayedID,self.session.nextID,self.sid)
                self.abort("Incorrect Session")
    #            return self.outputPhase() # or redirect
    #            self.redirect(self.HOME_URL)
    #            self.redirect(users.create_logout_url(HOME_PAGE)) # HOME_PAGE)
                return      


    def get(self):
        """ Handler for get - redirects to the login page if necessary, otherwise
            calls our subclass to generate the response.
        """
        self.t0 = datetime.utcnow()
        self.sid = self.request.get(SID_ID)
        logging.info("get Body: ["+self.request.body+"] "+
                     "Query: ["+self.request.query_string+"] "+
                     "Path: ["+str(self.request.path)+"] ") 
        self.senderID=None
        # self.senderID = json.loads(self.request.body)["ID"]
        logging.info(self.senderID)
        logging.info(self.request.url)
        response = self.getResponse()
        if response:
            self.response.out.write(response)
        #else:
        #    self.abort("Invalid Response")
  
    post=get


    def getGenerationDetails(self):
        '''time specnt,...
        '''
        if self.session:
            last=str(max(timedelta(seconds=0),self.session.lastAccess - self.session.startTime))
            ti=str(setDT(self.session.timeElapsed))
        else:
            last=''
            ti=''
        tt= datetime.utcnow() - self.t0
        return (last, ti, str(tt), Revision.revisionNumber)

    